package com.acegear.horizon.domain.events.handlers;

import com.acegear.horizon.domain.events.*;
import com.acegear.horizon.domain.models.Comment;
import com.acegear.horizon.domain.models.Post;
import com.acegear.horizon.domain.models.User;
import com.acegear.horizon.domain.models.constraint.FeedType;
import com.acegear.horizon.domain.models.jpa.PostComment;
import com.acegear.horizon.domain.models.jpa.PostLike;
import com.acegear.horizon.domain.models.jpa.UserInfo;
import com.acegear.horizon.domain.models.jpa.UserPost;
import com.acegear.horizon.domain.repository.ClubRepository;
import com.acegear.horizon.domain.repository.CommentRepository;
import com.acegear.horizon.domain.repository.PostRepository;
import com.acegear.horizon.domain.repository.UserRepository;
import com.acegear.horizon.domain.repository.jpa.PostLikeRepository;
import com.acegear.horizon.domain.repository.jpa.UserInfoRepository;
import com.acegear.horizon.domain.repository.jpa.UserPostRepository;
import com.acegear.horizon.vendor.ons.ONSConsumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


/**
 * Created by wangsike on 2016/12/21.
 */
@Component
public class UserEventHandler {

    @Autowired
    private UserPostRepository userPostRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PostRepository postRepository;
    @Autowired
    private ClubRepository clubRepository;
    @Autowired
    private PostLikeRepository postLikeRepository;
    @Autowired
    private CommentRepository commentRepository;

    @Autowired
    private ONSConsumer consumer;

    @PostConstruct
    public void userLoginONS() {
        consumer.consume(UserLoginEvent.class, this::userLogin);
    }

    @PostConstruct
    public void userRegisterONS() {
        consumer.consume(UserRegisterEvent.class, this::userRegister);
    }

    @PostConstruct
    public void userModifiedONS() {
        consumer.consume(UserInfoUpdateEvent.class, this::userModified);
    }

    @PostConstruct
    public void userDeleteONS() {
        consumer.consume(UserDeleteEvent.class, this::userDelete);
    }

    @PostConstruct
    public void userPostONS() {
        consumer.consume(UserPostEvent.class, this::userPost);
    }

    @PostConstruct
    public void userPostLikeONS() {
        consumer.consume(PostLikeEvent.class, this::userPostLike);
    }

    @PostConstruct
    public void userModifiedPostONS() {
        consumer.consume(UserPostModifiedEvent.class, this::userModifiedPost);
    }

    @PostConstruct
    public void userRestorePostONS() {
        consumer.consume(UserPostRestoreEvent.class, this::userRestorePost);
    }

    @PostConstruct
    public void userDeletePostONS() {
        consumer.consume(UserPostDeleteEvent.class, this::userDeletePost);
    }

    @PostConstruct
    public void userPostCommentCreateONS() {
        consumer.consume(PostCommentCreateEvent.class, this::userPostCommentCreate);
    }

    @PostConstruct
    public void userPostCommentDeleteONS() {
        consumer.consume(PostCommentDeleteEvent.class, this::userPostCommentDelete);
    }

    @PostConstruct
    public void userTransferONS() {
        consumer.consume(UserTransferEvent.class, this::userTransfer);
    }

    @PostConstruct
    public void userJoinONS() {
        consumer.consume(UserJoinClubEvent.class, this::userJoin);
    }

    @PostConstruct
    public void userLeaveONS() {
        consumer.consume(UserLeaveClubEvent.class, this::userLeave);
    }

    public void userLogin(UserLoginEvent loginEvent) {
        //TODO 记录
    }

    /**
     * type = 5 服务器添加的用户
     */
    public void userRegister(UserRegisterEvent registerEvent) {
        if (registerEvent.getType() == UserRegisterEvent.RegisterType.MANAGEMENT) {
            UserInfo userInfo = new UserInfo(registerEvent.getUserId(), registerEvent.getNickname(), registerEvent.getAvatar(), registerEvent.getGender(), registerEvent.getProvince(), registerEvent.getTitle());
            User.manageUserRegister(userInfo);
        }
    }

    @Transactional
    public void userModified(UserInfoUpdateEvent userInfoUpdateEvent) {
        if (userInfoUpdateEvent.getType() == UserInfoUpdateEvent.UpdateType.MANAGEMENT) {

            Optional<UserInfo> userInfoOptional = userInfoRepository.findByUserId(userInfoUpdateEvent.getUserId());
            if (userInfoOptional.isPresent()) {
                UserInfo userInfo1 = userInfoOptional.get();
                userInfo1.setAvatar(userInfoUpdateEvent.getAvatar());
                userInfo1.setNickname(userInfoUpdateEvent.getNickname());
                userInfo1.setGender(userInfoUpdateEvent.getGender());
                userInfo1.setProvince(userInfoUpdateEvent.getProvince());
                userInfo1.setTitle(userInfoUpdateEvent.getTitle());
                userInfoRepository.save(userInfo1);
            }
        }
    }

    @Transactional
    public void userDelete(UserDeleteEvent userDeleteEvent) {
        if (userDeleteEvent.getType() == UserDeleteEvent.DeleteType.MANAGEMENT) {
            Optional<UserInfo> userInfo = userInfoRepository.findByUserId(userDeleteEvent.getUserId());
            if (userInfo.isPresent()) {
                User.delete(userInfo.get());
            }
        }
    }

    public void userPost(UserPostEvent postEvent) {
        if (postEvent.getEventType() == PostEventType.MANAGEMENT) {
            UserPost userPost = new UserPost(
                    postEvent.getPostId(),
                    postEvent.getClubId(),
                    postEvent.getUserId(),
                    postEvent.getPostType(),
                    postEvent.getContentPartList(),
                    false
            );
            Post post = new Post(userPost);
            post.save();
            //添加clubFeed数据
            clubRepository.saveFeed(FeedType.USER_POST, userPost.getClubId(), post.getPostId());
        }
    }

    public void userPostLike(PostLikeEvent postLikeEvent) {
        Optional<Post> postOptional = postRepository.findByPostId(postLikeEvent.getPostId());
        List<PostLike> postLikeList = new ArrayList<>();
        if (postOptional.isPresent()) {
            postLikeEvent.getUserId().forEach((userId -> {
                if (!postLikeRepository.findTopByUserIdAndPostId(userId, postLikeEvent.getPostId()).isPresent()) {
                    postLikeList.add(new PostLike(postLikeEvent.getPostId(), userId));
                }
            }));
            postLikeRepository.save(postLikeList);
        }
    }

    @Transactional
    public void userModifiedPost(UserPostModifiedEvent userPostModifiedEvent) {
        if (userPostModifiedEvent.getEventType() == PostEventType.MANAGEMENT) {
            Optional<UserPost> postOptional = userPostRepository.findByPostId(userPostModifiedEvent.getPostId());
            if (postOptional.isPresent()) {
                UserPost userPost1 = postOptional.get();
                userPost1.setClubId(userPostModifiedEvent.getClubId());
                userPost1.setUserId(userPostModifiedEvent.getUserId());
                userPost1.setPostType(userPostModifiedEvent.getPostType());
                userPost1.setContents(userPostModifiedEvent.getContentPartList());
                Post post = new Post(userPost1);
                post.save();
            }
        }
    }

    @Transactional
    public void userRestorePost(UserPostRestoreEvent userPostRestoreEvent) {
        if (userPostRestoreEvent.getEventType() == PostEventType.MANAGEMENT) {

            Optional<UserPost> postOptional = userPostRepository.findByPostId(userPostRestoreEvent.getPostId());
            if (postOptional.isPresent()) {
                UserPost userPost1 = postOptional.get();
                userPost1.setDeleted(false);
                userPost1.setClubId(userPostRestoreEvent.getClubId());
                userPost1.setUserId(userPostRestoreEvent.getUserId());
                userPost1.setPostType(userPostRestoreEvent.getPostType());
                userPost1.setContents(userPostRestoreEvent.getContentPartList());
                Post post = new Post(userPost1);
                post.save();
            }
            //添加clubFeed数据
            clubRepository.saveFeed(FeedType.USER_POST, userPostRestoreEvent.getClubId(), userPostRestoreEvent.getPostId());

        }
    }

    @Transactional
    public void userDeletePost(UserPostDeleteEvent userPostDeleteEvent) {
        if (userPostDeleteEvent.getEventType() == PostEventType.MANAGEMENT) {
            Optional<Post> postOptional = postRepository.findByPostId(userPostDeleteEvent.getPostId());
            if (postOptional.isPresent()) {
                UserPost userPost = postOptional.get().getUserPost();
                postOptional.get().deleteManagePost(userPostDeleteEvent.getReason());
                // 删除帖子后ClubFeed表里删除该条数据
                clubRepository.deleteFeed(FeedType.USER_POST, userPost.getClubId(), userPost.getPostId());
            }
        }
    }

    public void userPostCommentCreate(PostCommentCreateEvent postCommentCreateEvent) {
        if (postCommentCreateEvent.getEventType() == PostEventType.MANAGEMENT) {
            PostComment postComment = new PostComment(postCommentCreateEvent.getCommentId(),
                    postCommentCreateEvent.getPostId(),
                    postCommentCreateEvent.getUserId(),
                    commentRepository.getCurrentFloor(postCommentCreateEvent.getPostId()) + 1,
                    postCommentCreateEvent.getReplyTo(),
                    postCommentCreateEvent.getReplyFloor(),
                    postCommentCreateEvent.getContents(),
                    false
            );
            Comment comment = new Comment(postComment);
            comment.save();
        }
    }

    @Transactional
    public void userPostCommentDelete(PostCommentDeleteEvent postCommentDeleteEvent) {
        if (postCommentDeleteEvent.getEventType() == PostEventType.MANAGEMENT) {
            Optional<Comment> comment = commentRepository.findCommentId(postCommentDeleteEvent.getCommentId());
            if (!comment.isPresent()) {
                comment.get().deleteManageComment(postCommentDeleteEvent.getReason());
            }
        }
    }

    @Transactional
    public void userTransfer(UserTransferEvent userTransferEvent) {
        Optional<User> userOptional = userRepository.findByUserId(userTransferEvent.getUserId());
        userOptional.ifPresent(
                user -> {
                    user.setPhone(userTransferEvent.getPhone(), true);
                    user.getPasswordAuth().setPassword(userTransferEvent.getPassword());
                    user.save();
                }
        );
    }

    public void userJoin(UserJoinClubEvent joinClubEvent) {
    }

    public void userLeave(UserLeaveClubEvent userLeaveClubEvent) {
    }
}
